package bancosys.tec.datadigester.registry.impl;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;

import jmine.tec.datadigester.DataDigesterMessages;

import org.springframework.core.io.Resource;

import bancosys.tec.datadigester.registry.DriverRegistry;
import bancosys.tec.datadigester.registry.DriverRegistryLoader;
import bancosys.tec.datadigester.registry.DriverRegistryLoaderException;

/**
 * Implementação de carregador de registro de driver que lê um arquivo .properties.
 * 
 * @author hugo
 */
public class PropertiesRegistryLoader implements DriverRegistryLoader {

    /**
     * Arquivo properties com a configuração do registro de drivers a ser carregado.
     */
    private Resource propertiesFile;

    /**
     * @param propertiesFile The filepath to load the registry.
     */
    public PropertiesRegistryLoader(Resource propertiesFile) {
        this.propertiesFile = propertiesFile;
    }

    /**
     * @see bankware.datadigester.DriverRegistryLoader#load()
     * @return The loaded driver registry
     */
    public DriverRegistry load() {
        if (this.propertiesFile == null || !this.propertiesFile.exists()) {
            throw new DriverRegistryLoaderException(DataDigesterMessages.DRIVERS_FILE_NOT_INJECTED.create());
        }
        DriverRegistry registry = new DriverRegistry();
        Properties properties = this.loadProperties();
        this.populateRegistry(registry, properties);
        return registry;
    }

    /**
     * The method ignores uncheck warnings because properties are not forced to use Strings as keys although they are always Strings.
     * 
     * @param registry The registry to be populated
     * @param properties The properties object containg the informations
     */
    @SuppressWarnings("unchecked")
    private void populateRegistry(DriverRegistry registry, Properties properties) {
        Enumeration<String> fileNames = (Enumeration<String>) properties.propertyNames();
        while (fileNames.hasMoreElements()) {
            String fileCode = fileNames.nextElement();
            String driverClass = properties.getProperty(fileCode);
            registry.register(fileCode, driverClass);
        }
    }

    /**
     * @return The Properties object loaded.
     */
    private Properties loadProperties() {
        Properties properties = new Properties();
        try {
            InputStream resourceAsStream = this.propertiesFile.getInputStream();
            properties.load(resourceAsStream);
        } catch (IOException e) {
            throw new DriverRegistryLoaderException(DataDigesterMessages.ERROR_READING_DRIVERS_FILE.create(this.propertiesFile), e);
        }
        return properties;
    }

    /**
     * {@inheritDoc}
     */
    public Map<String, String> driverProperties(String fullQualifiedName) {
        return Collections.emptyMap();
    }
}
